import "./index.css";
import clsx from "classnames";
import { useState, useEffect } from "react";
import { GridBoxProps } from "./type";
import { Key } from "../factory/type";

const GridBox = <T extends Record<string, any>>(props: GridBoxProps<T>) => {
  const {
    size,
    className,
    style,
    items,
    itemCls,
    itemActiveCls = "",
    onChange,
    value,
    defaultValue,
    allowClear = true,
  } = props;

  const isControlled = typeof value !== "undefined";
  const initialVal = isControlled ? value : defaultValue ?? null;

  const [activeKey, setActiveKey] = useState<Key>(initialVal);

  useEffect(() => {
    if (typeof value !== "undefined") {
      setActiveKey(value);
    }
  }, [value]);

  const handleChange = (result: Key) => {
    onChange?.(result);
    if (!isControlled) {
      setActiveKey(result);
    }
  };

  return (
    <div style={{ ...style, width: size, height: size }} className={clsx("grid-box-container", className)}>
      {items.map((item) => {
        const { key, render } = item;

        return (
          <div
            key={key as string}
            className={clsx(
              "grid-box-item",
              {
                active: activeKey === key,
                [itemActiveCls]: activeKey === key,
              },
              itemCls
            )}
            style={{
              width: `${100 / Math.sqrt(items.length)}%`,
            }}
            onClick={() => {
              if (allowClear) {
                handleChange(activeKey === key ? null : key);
              } else {
                if (activeKey !== key) {
                  handleChange(key);
                }
              }
            }}
          >
            {typeof render === "function" ? render() : render}
          </div>
        );
      })}
    </div>
  );
};

export default GridBox;
